#pragma once

#include "color.h"

#ifdef __cplusplus
extern "C"
{
#endif

	typedef struct NX_Surface
	{
		int width;
		int height;
		int stride;
		int pixlen;
		NX_Color *pixels;
	} NX_Surface;

	typedef struct NX_Region
	{
		int x;
		int y;
		int w;
		int h;
	} NX_Region;

	NX_INLINE int NX_RegionIsEmpty(NX_Region r)
	{
		if ((r.w > 0) && (r.h > 0))
			return 0;
		return 1;
	}

	NX_INLINE int NX_RegionHit(struct NX_Region r, int x, int y)
	{
		if ((x >= r.x) && (x < r.x + r.w) && (y >= r.y) && (y < r.y + r.h))
			return 1;
		return 0;
	}

	NX_INLINE int NX_RegionContains(struct NX_Region r, struct NX_Region o)
	{
		int rr = r.x + r.w;
		int rb = r.y + r.h;
		int or = o.x + o.w;
		int ob = o.y + o.h;
		if ((o.x >= r.x) && (o.x < rr) && (o.y >= r.y) && (o.y < rb) && (or > r.x) && (or <= rr) && (ob > r.y) && (ob <= rb))
			return 1;
		return 0;
	}

	NX_INLINE NX_Region NX_RegionIntersect(NX_Region a, NX_Region b)
	{
		NX_Region r = {};

		int x0 = NX_MAX(a.x, b.x);
		int x1 = NX_MIN(a.x + a.w, b.x + b.w);
		if (x0 <= x1)  
		{
			int y0 = NX_MAX(a.y, b.y);
			int y1 = NX_MIN(a.y + a.h, b.y + b.h);
			if (y0 <= y1)
			{
				r.x = x0;
				r.y = y0;
				r.w = x1 - x0;
				r.h = y1 - y0;
			}
		}
		return r;
	}

	NX_INLINE NX_Region NX_RegionMerge(NX_Region a, NX_Region b)
	{
		NX_Region r = {};
		int ar = a.x + a.w;
		int ab = a.y + a.h;
		int br = b.x + b.w;
		int bb = b.y + b.h;
		r.x = NX_MIN(a.x, b.x);
		r.y = NX_MIN(a.y, b.y);
		r.w = NX_MAX(ar, br) - r.x;
		r.h = NX_MAX(ab, bb) - r.y;
		return r;
	}

	NX_Surface *NX_SurfaceAlloc(int width, int height);
	NX_Surface *NX_SurfaceCopy(NX_Surface *s);
	void NX_SurfaceFree(NX_Surface *s);
	void NX_SurfaceWrap(NX_Surface *s, NX_Color *c, int w, int h);
	NX_Surface *NX_SurfaceAllocWrap(NX_Color *c, int width, int height);
	void NX_SurfaceClear(NX_Surface *s, NX_Color c, int x, int y, int w, int h);
	void NX_SurfaceBlit(NX_Surface *d, NX_Surface *s, int x, int y);
	void NX_SurfaceCover(NX_Surface *d, NX_Surface *s, int x, int y);
	NX_Surface *NX_SurfaceClone(NX_Surface *s, int x, int y, int w, int h);
	void NX_SurfaceMono(NX_Surface *s, NX_Color color);
	void NX_SurfaceFilterBlur(struct NX_Surface *s, int radius);
	void NX_SurfaceFilterOpacity(struct NX_Surface *s, int a);
	void NX_SurfaceMask(NX_Surface *d, NX_Surface *s, int x, int y);
	void NX_SurfaceBlitRegion(NX_Surface *d, NX_Surface *s, NX_Region dst, NX_Region src);
	void NX_SurfaceBlitRegionXY(NX_Surface *d, NX_Surface *s, NX_Region dst, int x, int y);
	void NX_SurfaceBlitWithOpacity(NX_Surface *d, NX_Surface *s, int x, int y, int a);
	void NX_SurfaceSetPixel(NX_Surface *s, NX_Color color, int x, int y);
	void NX_SurfaceCompositeOut(NX_Surface *d, NX_Surface *s, int x, int y);
	void NX_SurfaceBlitScaled(NX_Surface *dst, NX_Region *dstRect, NX_Surface *src, NX_Region *srcRect);
	void NX_SurfaceFullscreen(NX_Surface *dest, NX_Surface *src, int fit);

#ifdef __cplusplus
}
#endif